﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEditor;
using UnityEngine.UIElements;
using UnityEngine;
using Object = UnityEngine.Object;
using System.IO;
using ZyGame.Editor.AssetBuilder;
using System.Collections;
using ZyGame.Execute;
using Unity.EditorCoroutines.Editor;
using UnityEngine.Networking;
using ZyGame.Editor.Tools;
using ZyGame.Avatar;
using System.Reflection;

namespace ZyGame.Editor.CloudBuilder
{
    internal class CloudBuildClient : ZyEditorWindow
    {
        private bool isOptions = false;
        private float lastRefershTime = 0f;
        private float refreshIntervalTime = 10;
        private List<BuildData> waitingBuildList = new List<BuildData>();
        private Dictionary<string, bool> foldouts = new Dictionary<string, bool>();
        private List<Object> fileList = new List<Object>();
        private Vector2 scrollFileList = Vector2.zero;
        private string bundleName;
        private Platform platform;
        private List<string> downloadList = new List<string>();

        private void Awake()
        {
            lastRefershTime = Time.realtimeSinceStartup;
            RefreshBuildList();
        }

        private void Update()
        {
            if (Application.isPlaying)
            {
                return;
            }
            if (Time.realtimeSinceStartup - lastRefershTime < refreshIntervalTime)
            {
                return;
            }
            lastRefershTime = Time.realtimeSinceStartup;
            RefreshBuildList();
        }

        protected override void OnDrawToobar()
        {
            if (GUILayout.Button("Options", EditorStyles.toolbarButton))
            {
                isOptions = !isOptions;
            }
            GUILayout.FlexibleSpace();
            if (GUILayout.Button("下载", EditorStyles.toolbarButton))
            {
                this.StartCoroutine(StartDownload());
            }
        }

        protected override void OnDrawDataView()
        {
            if (isOptions)
            {
                CloudBuildOptions.instance.OnGUI();
            }
            else
            {
                ShowBuildListView();
            }
        }
        protected override void OnDrawBottom()
        {
            GUILayout.BeginVertical();
            if (!isOptions)
            {
                GUILayout.Space(10);
                GUILayout.BeginHorizontal();
                GUILayout.Label("Package Name");
                bundleName = GUILayout.TextField(bundleName, GUILayout.Width(300));
                GUILayout.FlexibleSpace();
                platform = (Platform)EditorGUILayout.EnumPopup(platform);
                if (GUILayout.Button("Create"))
                {
                    if (bundleName.IsNullOrEmpty())
                    {
                        EditorUtility.DisplayDialog("提示", "请输入包名", "OK");
                        return;
                    }
                    if (fileList.Count == 0)
                    {
                        EditorUtility.DisplayDialog("提示", "资源不能为空", "OK");
                        return;
                    }
                    CreateBuilder();
                }
                GUILayout.EndHorizontal();
                Rect rect = EditorGUILayout.BeginVertical(EditorStyles.helpBox, GUILayout.Height(150));
                scrollFileList = GUILayout.BeginScrollView(scrollFileList);
                for (int i = 0; i < fileList.Count; i++)
                {
                    GUILayout.BeginHorizontal();
                    EditorGUILayout.ObjectField(fileList[i], typeof(Object), false);
                    if (GUILayout.Button("-", GUILayout.Width(20)))
                    {
                        fileList.Remove(fileList[i]);
                        this.Repaint();
                    }
                    GUILayout.EndHorizontal();
                }
                GUILayout.EndScrollView();
                GUILayout.FlexibleSpace();
                this.CheckMouseDragEvent(rect);
                if (this.CheckMouseDragdropEvent(rect))
                {
                    fileList.AddRange(DragAndDrop.objectReferences);
                }

                GUILayout.EndVertical();
            }
            GUILayout.EndVertical();
        }

        private void CreateBuilder()
        {
            BuildData buildData = new BuildData();
            buildData.files = new List<string>();
            for (int i = 0; i < fileList.Count; i++)
            {
                string path = AssetDatabase.GetAssetPath(fileList[i]);
                if (Path.GetExtension(path).IsNullOrEmpty() is false)
                {
                    buildData.files.Add(path.NormalPath());
                    continue;
                }
                SearchSubFloderFiles(path, buildData);
            }
            buildData.time = DateTime.Now;
            buildData.State = TaskState.Waiting;
            buildData.platform = platform;
            buildData.pid = CloudBuildOptions.instance.pid;
            buildData.bundleName = bundleName;
            bundleName = string.Empty;
            fileList.Clear();

            IEnumerator WaitingUpload()
            {
                EditorUtility.DisplayProgressBar("提示", "正在上传资源...", 0);
                for (int i = 0; i < buildData.files.Count; i++)
                {
                    //string pid = CloudBuildOptions.instance.pid;
                    //string file = buildData.files[i];
                    //string bucket = CloudBuildOptions.instance.bucket;
                    //string region = CloudBuildOptions.instance.ap;
                    //string key = CloudBuildOptions.instance.SecretId;
                    //string pass = CloudBuildOptions.instance.SecretKey;
                    //UnityWebRequest upload = Api.UploadFileData(pid, file, bucket, region, key, pass, File.ReadAllBytes(file));

                    COS.PutObject(CloudBuildOptions.instance.bucket, CloudBuildOptions.instance.pid + "/" + buildData.files[i], buildData.files[i]);
                    yield return new WaitForSeconds(0.01f);
                    EditorUtility.DisplayProgressBar("提示", "正在上传资源...", i / (float)buildData.files.Count);
                }
                EditorUtility.ClearProgressBar();
            }
            IEnumerator Running()
            {
                yield return WaitingUpload();
                UnityWebRequest request = Api.NewBuild(buildData);
                yield return request.SendWebRequest();
                if (request.isDone is false || request.result is not UnityWebRequest.Result.Success)
                {
                    yield break;
                }
                BuildData buildDatas = Newtonsoft.Json.JsonConvert.DeserializeObject<BuildData>(request.downloadHandler.text);
                if (buildDatas is null)
                {
                    yield break;
                }
                RefreshBuildList();
            }
            this.StartCoroutine(Running());
        }

        private void RefreshBuildList()
        {

            IEnumerator Running()
            {
                waitingBuildList.Clear();
                UnityWebRequest request = Api.GetBuildList(BuildTarget.NoTarget);
                request.SetRequestHeader("Content-Type", "application/json");

                yield return request.SendWebRequest();
                if (request.isDone is false || request.result is not UnityWebRequest.Result.Success)
                {
                    Client.Console.WriteLine(request.error);
                    yield break;
                }
                List<BuildData> buildDatas = Newtonsoft.Json.JsonConvert.DeserializeObject<List<BuildData>>(request.downloadHandler.text);
                if (buildDatas is null || buildDatas.Count is 0)
                {
                    yield break;
                }
                waitingBuildList.AddRange(buildDatas);
                this.Repaint();
            }
            this.StartCoroutine(Running());
        }

        private void SearchSubFloderFiles(string path, BuildData buildData)
        {
            string[] f = AssetDatabase.GetSubFolders(path);
            if (f is not null && f.Length > 0)
            {
                for (int i = 0; i < f.Length; i++)
                {
                    SearchSubFloderFiles(f[i], buildData);
                }
            }
            string[] files = Directory.GetFiles(path);
            if (files is null || files.Length is 0)
            {
                return;
            }
            for (int i = 0; i < files.Length; i++)
            {
                if (files[i].EndsWith(".meta"))
                {
                    continue;
                }
                buildData.files.Add(files[i].NormalPath());
            }
        }


        private void ShowBuildListView()
        {
            for (int i = 0; i < waitingBuildList.Count; i++)
            {
                BuildData buildData = waitingBuildList[i];
                Rect rect = EditorGUILayout.BeginVertical(downloadList.Contains(buildData.download) ? EditorStyles.selectionRect : EditorStyles.helpBox);
                GUILayout.BeginHorizontal();
                GUILayout.Label("Project Id:", GUILayout.Width(150));
                GUILayout.Label(buildData.pid);
                GUILayout.EndHorizontal();

                GUILayout.BeginHorizontal();
                GUILayout.Label("Task Id:", GUILayout.Width(150));
                GUILayout.Label(buildData.id);
                GUILayout.EndHorizontal();

                GUILayout.BeginHorizontal();
                GUILayout.Label("Time:", GUILayout.Width(150));
                GUILayout.Label(buildData.time.ToString("G"));
                GUILayout.EndHorizontal();

                GUILayout.BeginHorizontal();
                GUILayout.Label("State:", GUILayout.Width(150));
                GUILayout.Label(buildData.State.ToString());
                GUILayout.EndHorizontal();

                GUILayout.BeginHorizontal();
                GUILayout.Label("Platform:", GUILayout.Width(150));
                GUILayout.Label(buildData.platform.ToString());
                GUILayout.EndHorizontal();
                GUILayout.BeginHorizontal();
                GUILayout.Label("Download:", GUILayout.Width(150));
                GUILayout.Label(buildData.download);
                GUILayout.EndHorizontal();
                if (!foldouts.TryGetValue(buildData.id, out bool state))
                {
                    foldouts.Add(buildData.id, false);
                }
                foldouts[buildData.id] = EditorGUILayout.Foldout(state, "Files");
                if (foldouts[buildData.id])
                {
                    for (int j = 0; j < buildData.files.Count; j++)
                    {
                        GUILayout.Label(buildData.files[j]);
                    }
                }
                if (this.CheckMouseClickEvent(rect))
                {
                    if (downloadList.Contains(buildData.download))
                    {
                        downloadList.Remove(buildData.download);
                    }
                    else
                    {
                        downloadList.Add(buildData.download);
                    }
                    this.Repaint();
                }
                GUILayout.EndVertical();
            }
        }


        private IEnumerator StartDownload()
        {
            string lastSavePath = EditorPrefs.GetString("download", Application.dataPath);
            string local = EditorUtility.OpenFolderPanel("选择保存文件夹", lastSavePath, lastSavePath);
            EditorPrefs.SetString("download", local);
            EditorUtility.DisplayProgressBar("提示", "正在下载资源包...", 0);
            for (int i = 0; i < downloadList.Count; i++)
            {
                UnityWebRequest request = UnityWebRequest.Get(downloadList[i]);
                yield return request.SendWebRequest();
                if (request.isDone && request.result is UnityWebRequest.Result.Success)
                {
                    File.WriteAllBytes(local + "/" + Path.GetFileName(downloadList[i]), request.downloadHandler.data);
                }
                EditorUtility.DisplayProgressBar("提示", "正在下载资源包...", i / (float)downloadList.Count);
            }
            EditorUtility.ClearProgressBar();
            EditorUtility.DisplayDialog("提示", "下载完成！", "OK");
            downloadList.Clear();
        }
    }
}
